/**
 * @Project TestOkHttp
 * @Filename HttpUtils.java
 * @Package com.nico.testokhttp
 * @Description TODO
 * @Author wifiunion
 * @Creation 2016年5月5日 下午2:15:53
 * @Modification 2016年5月5日 下午2:15:53
 * @Copyright Copyright © 2012 - 2016 wifiunion.All Rights Reserved.
 **/
package wifiunion.com.notice;

import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Handler;
import android.os.Looper;
import android.text.TextUtils;
import android.widget.ImageView;

import com.google.gson.Gson;

import org.json.JSONObject;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.FileNameMap;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Headers;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.ResponseBody;

import static wifiunion.com.notice.Constants.HTTP_URL_GET_CLOUD_SERVERVERSION;


/**
 * @ClassName HttpUtils
 * @Description TODO
 * @Version
 * @Author wifiunion
 * @Creation 2016年5月5日 下午2:15:53
 * @Modification 2016年5月5日 下午2:15:53
 **/
public class HttpUtils {
    private static HttpUtils mInstance;
    private OkHttpClient mOkHttpClient;
    /**
     * json 类型
     */
    public static final MediaType MEDIA_TYPE_JSON = MediaType.parse("application/json; charset=utf-8");

    /**
     * 上传文件用的到流类型
     */
    private static final MediaType MEDIA_TYPE_IMG = MediaType.parse("application/octet-stream");

    private static final String TAG = "HttpUtils";

    private Handler mDelivery;

    private HttpUtils() {
//        mOkHttpClient = new OkHttpClient();
//        mOkHttpClient.setConnectTimeout(30, TimeUnit.SECONDS);
//        mOkHttpClient.setWriteTimeout(30, TimeUnit.SECONDS);
//        mOkHttpClient.setReadTimeout(30, TimeUnit.SECONDS);


        mOkHttpClient = new OkHttpClient.Builder()
                .connectTimeout(30, TimeUnit.SECONDS)
                .readTimeout(30, TimeUnit.SECONDS)
                .writeTimeout(30, TimeUnit.SECONDS)
                .build();


        // 设置缓存
//        File sdcache = context.getExternalCacheDir();
//        int cacheSize = 50 * 1024 * 1024; // 10 MiB

        mDelivery = new Handler(Looper.getMainLooper());
//        mOkHttpClient.networkInterceptors().add(new StethoInterceptor());
//        mOkHttpClient.setCache(new Cache(sdcache.getAbsoluteFile(), cacheSize));
    }

    public static HttpUtils getInstance() {
        if (mInstance == null) {
            synchronized (HttpUtils.class) {
                if (mInstance == null) {
                    mInstance = new HttpUtils();
                }
            }
        }
        return mInstance;
    }


    /**
     * @param url
     * @param params
     * @param type
     * @return void
     * @throws UnsupportedEncodingException
     * @Name _getAsyn
     * @Description 异步的get请求
     * @Author wifiunion
     * @Date 2016年5月5日 下午3:57:40
     */
    private void HttpGetRequest_Asyn_Real(String url, HashMap<String, Object> params, BaseCallBack callback,
                                          java.lang.reflect.Type type) {


        StringBuffer requesturl = new StringBuffer("");

        if (url.equals(Constants.CONSTANT_CHECKUPDATE_URL)) {
            requesturl = new StringBuffer(Constants.CONSTANT_CHECKUPDATE_URL);
        } else if (url.equals(Constants.CONSTANT_CHECKUPDATE_URL_CUSTOM)) {
            requesturl = new StringBuffer(Constants.CONSTANT_CHECKUPDATE_URL_CUSTOM);
        } else if (url.equals(Constants.HTTP_URL_GET_VERIFY)) {
            requesturl = new StringBuffer(Constants.HTTP_URL_ICLOUD + url);
        } else if (url.equals(Constants.HTTP_URL_GET_ICLOUDLOGIN)) {
            requesturl = new StringBuffer(Constants.HTTP_URL_ICLOUD + url);
        } else if (url.equals(Constants.HTTP_URL_GET_ICLOUDREG)) {
            requesturl = new StringBuffer(Constants.HTTP_URL_ICLOUD + url);
        } else if (url.equals(Constants.HTTP_URL_GET_ICLOUDPASSWORD)) {
            requesturl = new StringBuffer(Constants.HTTP_URL_ICLOUD + url);
        } else if (url.equals(Constants.HTTP_URL_GET_CLOUDPLACE)) {
            requesturl = new StringBuffer(Constants.HTTP_URL_ICLOUD + url);
        } else if (url.equals(HTTP_URL_GET_CLOUD_SERVERVERSION)) {
            requesturl = new StringBuffer(Constants.HTTP_URL_ICLOUD + url);
        } else if (url.equals(Constants.HTTP_URL_GET_CLOUD_APPVERSION)) {
            requesturl = new StringBuffer(Constants.HTTP_URL_ICLOUD + url);
        } else if (url.equals(Constants.HTTP_URL_GET_UPDATE_DETECT)) {
            requesturl = new StringBuffer(Constants.HTTP_URL_ICLOUD + url);
        } else if (url.equals(Constants.HTTP_URL_GET_EXCHANGE_PACKAGE)) {
            requesturl = new StringBuffer(Constants.HTTP_URL_ICLOUD + url);
        } else if (url.equals(Constants.HTTP_URL_GET_SMS_ORDERLIST)) {
            requesturl = new StringBuffer(Constants.HTTP_URL_ICLOUD + url);
        } else if (url.equals(Constants.HTTP_URL_GET_PLUGINLIST)) {
            requesturl = new StringBuffer(Constants.HTTP_URL_ICLOUD + url);
        } else {
            requesturl = new StringBuffer(Constants.HTTP_URL_HEADER + url);
        }
        String authtoken = "";
        // 有参数
        if (!params.isEmpty()) {
            // 有auth
            if (params.containsKey("Authorization")) {
                // 添加Authorization
                authtoken = (String) params.get("Authorization");
                if (TextUtils.isEmpty(authtoken)) {
                    return;
                }
                params.remove("Authorization");
            }
            // 拼接httpurl
            Iterator iter = params.entrySet().iterator();
            while (iter.hasNext()) {
                HashMap.Entry<String, Object> entry = (HashMap.Entry<String, Object>) iter.next();
                Object paramname = entry.getKey();
                Object paramvalue = entry.getValue();
                try {
                    requesturl.append(paramname + "=" + paramvalue + "&");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

        }
        if (requesturl.lastIndexOf("&") == requesturl.length() - 1) {
            requesturl.deleteCharAt(requesturl.length() - 1);
        }

        Request request;

        try {

            if (TextUtils.isEmpty(authtoken)) {
                request = new Request.Builder().url(requesturl.toString()).build();
            } else {
                request = new Request.Builder().url(requesturl.toString()).addHeader("Authorization", authtoken).build();
            }

            deliveryHttpGetResult(request, callback, type);

        } catch (IllegalArgumentException e) {
            e.printStackTrace();
            callback.onServerFailed("服务器地址错误");


        }

    }


    private String getFileName(String path) {
        int separatorIndex = path.lastIndexOf("/");
        return (separatorIndex < 0) ? path : path.substring(separatorIndex + 1, path.length());
    }


    private void setErrorResId(final ImageView view, final int errorResId) {
        mDelivery.post(new Runnable() {
            @Override
            public void run() {
                view.setImageResource(errorResId);
            }
        });
    }


    /**
     * @param url
     * @param params
     * @param type
     * @return void
     * @throws UnsupportedEncodingException
     * @Name getAsyn
     * @Description 异步的httpget请求
     * @Author wifiunion
     * @Date 2016年5月5日 下午3:00:57
     */
    public static void HttpGetRequest_Asyn(String url, HashMap<String, Object> params, BaseCallBack callback,
                                           java.lang.reflect.Type type) {
        getInstance().HttpGetRequest_Asyn_Real(url, params, callback, type);
    }


    private Request buildMultipartFormRequest(String url, File[] files, String[] fileKeys, Param[] params) {
        params = validateParam(params);

//        MultipartBuilder builder = new MultipartBuilder().type(MultipartBuilder.FORM);

        MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM);
        for (Param param : params) {

            builder.addPart(Headers.of("Content-Disposition", "form-data; name=\"" + param.key + "\""),
                    RequestBody.create(null, param.value));
        }
        if (files != null) {
            RequestBody fileBody = null;
            for (int i = 0; i < files.length; i++) {
                File file = files[i];
                String fileName = file.getName();
                fileBody = RequestBody.create(MediaType.parse(guessMimeType(fileName)), file);
                builder.addPart(Headers.of("Content-Disposition",
                        "form-data; name=\"" + fileKeys[i] + "\"; filename=\"" + fileName + "\""), fileBody);
            }
        }

        RequestBody requestBody = builder.build();
        return new Request.Builder().url(url).post(requestBody).build();
    }

    private String guessMimeType(String path) {
        FileNameMap fileNameMap = URLConnection.getFileNameMap();
        String contentTypeFor = fileNameMap.getContentTypeFor(path);
        if (contentTypeFor == null) {
            contentTypeFor = "application/octet-stream";
        }
        return contentTypeFor;
    }

    private Param[] validateParam(Param[] params) {
        if (params == null)
            return new Param[0];
        else
            return params;
    }

    private Param[] map2Params(Map<String, String> params) {
        if (params == null)
            return new Param[0];
        int size = params.size();
        Param[] res = new Param[size];
        Set<Map.Entry<String, String>> entries = params.entrySet();
        int i = 0;
        for (Map.Entry<String, String> entry : entries) {
            res[i++] = new Param(entry.getKey(), entry.getValue());
        }
        return res;
    }

    private String map2JsonString(Map<String, Object> params) {
        if (params == null || params.isEmpty()) {
            return "";
        }
        Gson gson = new Gson();
        String jsonStr = gson.toJson(params);
        return jsonStr;
    }


    /**
     * @param request
     * @Name deliveryResult
     * @Description 发送请求请求
     * @rurn void
     * @Author wifiunion
     * @Date 2016年5月5日 下午3:06:57
     */
    private void deliveryHttpGetResult(Request request, final BaseCallBack callback, final java.lang.reflect.Type type
    ) {

        mOkHttpClient.newCall(request).enqueue(new Callback() {

            @Override
            public void onFailure(Call call, IOException e) {


                sendFailedCallback(callback, null);
//                callback.onNetFailed();
            }

            @Override
            public void onResponse(Call call, Response response) {

                try {
                    String respStr = response.body().string();
                    JSONObject jsonObject = new JSONObject(respStr);


                    if (jsonObject.has("messageCode") && "SYS9999".equals(jsonObject.getString("messageCode"))) {
//                        callback.onServerFailed(jsonObject.getString("message"));

                        sendFailedCallback(callback, jsonObject.getString("message"));
                    } else {
                        if (jsonObject.has("result")) {
                            if (1 == jsonObject.getInt("result")) {
                                if (jsonObject.has("data")) {
                                    if (type == null) {
//                                        callback.onSuccess(respStr);

                                        sendSuccessCallback(callback, respStr);
                                    } else {
                                        Gson gson = new Gson();
                                        String data = jsonObject.getString("data");
                                        Object result = gson.fromJson(data, type);
//                                        callback.onSuccess(result);


                                        sendSuccessCallback(callback, result);
                                    }

                                }
                            } else {
                                String msgCode = jsonObject.getString("messageCode");
                                if ((!TextUtils.isEmpty(msgCode)) && ("BUI0009".equals(msgCode) || "BUI0001".equals(msgCode))) {
                                    Intent intent = new Intent(Constants.LOGOUT_ACTION);
                                    if (!TextUtils.isEmpty(jsonObject.getString("message"))) {
                                        intent.putExtra("errormsg", jsonObject.getString("message"));
                                    } else {
                                        intent.putExtra("errormsg", "未知异常，请重新登录");
                                    }
                                    BaseApplication.mApplication.sendBroadcast(intent);
                                } else {
                                    sendFailedCallback(callback, jsonObject.getString("message"));
//                                    callback.onServerFailed(jsonObject.getString("message"));
                                }
                            }
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
//                    callback.onServerFailed(null);
                    sendFailedCallback(callback, null);
                }
            }
        });
    }


    /**
     * @param httpurl
     * @param params
     * @param type
     * @param needParse
     * @return void
     * @Name HttpPostRequest_Asyn_Real
     * @Description 异步的get请求
     * @Author wifiunion
     * @Date 2016年5月6日 上午11:18:43
     */
    private void HttpPostRequest_Asyn_Real(String httpurl, HashMap<String, Object> params, final BaseCallBack callback,
                                           final java.lang.reflect.Type type, final boolean needParse) {

        String authtoken = "";
        try {
            // 有参数
            if (!params.isEmpty()) {
                // 有auth
                if (params.containsKey("Authorization")) {
                    authtoken = (String) params.get("Authorization");
                    // 添加Authorization
                    params.remove("Authorization");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        String requestUrl = "";
        if (httpurl.equals(Constants.HTTP_URL_POST_CLOUDPLACE)) {
            requestUrl = Constants.HTTP_URL_ICLOUD + httpurl + Constants.ICLOUD_NAME;
        } else if (httpurl.equals(Constants.HTTP_URL_POST_SMS_GENERATEORDER)) {
            requestUrl = Constants.HTTP_URL_ICLOUD + httpurl;
        } else if (httpurl.equals(Constants.HTTP_URL_POST_UPLOAD_ORDERSTATUS)) {
            requestUrl = Constants.HTTP_URL_ICLOUD + httpurl;
        } else if (httpurl.equals(Constants.HTTP_URL_POST_DOWNLOADRECORD)) {
            requestUrl = Constants.HTTP_URL_ICLOUD + httpurl;
        } else {
            requestUrl = Constants.HTTP_URL_HEADER + httpurl;
        }

        // 这边设置下请求的数据格式以JSON传递
        RequestBody requestBody = RequestBody.create(MEDIA_TYPE_JSON, map2JsonString(params));
        Request request = null;
        if (!TextUtils.isEmpty(authtoken)) {
            request = new Request.Builder().url(requestUrl).post(requestBody).addHeader("Authorization", authtoken)
                    .build();
        } else {
            request = new Request.Builder().url(requestUrl).post(requestBody).build();
        }
        deliveryHttpPostResult(request, callback, type, needParse);

    }

    /**
     * @param httpurl
     * @param params
     * @param type
     * @return void
     * @Name HttpPutRequest_Asyn_Real
     * @Description put 请求
     * @Author wifiunion
     * @Date 2016年5月6日 下午4:30:16
     */
    private void HttpPutRequest_Asyn_Real(String httpurl, HashMap<String, Object> params, final BaseCallBack callback,
                                          final java.lang.reflect.Type type, Context context) {

        String authtoken = "";
        try {
            // 有参数
            if (!params.isEmpty()) {
                // 有auth
                if (params.containsKey("Authorization")) {
                    authtoken = (String) params.get("Authorization");
                    // 添加Authorization
                    params.remove("Authorization");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        String requestUrl = Constants.HTTP_URL_HEADER + httpurl;
        // 这边设置下请求的数据格式以JSON传递
        RequestBody requestBody = RequestBody.create(MEDIA_TYPE_JSON, map2JsonString(params));

        if (!TextUtils.isEmpty(authtoken)) {
            Request request = new Request.Builder().url(requestUrl).put(requestBody)
                    .addHeader("Authorization", authtoken).build();

            deliveryHttpPutResult(request, callback, type, context);
        }

    }

    /**
     * @param httpurl
     * @param authtoken
     * @param uuid
     * @param type
     * @return void
     * @Name HttpDelRequest_Asyn_Real
     * @Description TODO
     * @Author Administrator
     * @Date 2016年5月11日 上午9:11:15
     */
    private void HttpDelRequest_Asyn_Real(String httpurl, String authtoken, String uuid, final BaseCallBack callback,
                                          final java.lang.reflect.Type type, Context context) {

        String requestUrl = Constants.HTTP_URL_HEADER + httpurl + uuid;

        Request request = new Request.Builder().url(requestUrl).delete().addHeader("Authorization", authtoken).build();

        deliveryHttpDelResult(request, callback, type, context);
    }


    /**
     * @param httpurl
     * @param params
     * @param type
     * @param needParse
     * @return void
     * @Name HttpPostRequest_Asyn
     * @Description 开放的post请求
     * @Author wifiunion
     * @Date 2016年5月6日 下午4:40:10
     */
    public static void HttpPostRequest_Asyn(String httpurl, HashMap<String, Object> params,
                                            final BaseCallBack callback, final java.lang.reflect.Type type, final boolean needParse) {
        getInstance().HttpPostRequest_Asyn_Real(httpurl, params, callback, type, needParse);
    }

    /**
     * @param httpurl
     * @param params
     * @param type
     * @return void
     * @Name HttpPutRequest_Asyn
     * @Description 开放使用的http put请求
     * @Author wifiunion
     * @Date 2016年5月6日 下午4:39:39
     */
    public static void HttpPutRequest_Asyn(Context context, String httpurl, HashMap<String, Object> params,
                                           final BaseCallBack callback, final java.lang.reflect.Type type) {
        getInstance().HttpPutRequest_Asyn_Real(httpurl, params, callback, type, context);
    }

    /**
     * @param httpurl
     * @param authtoken
     * @param uuid
     * @param type
     * @return void
     * @Name HttpDelRequest_Asyn
     * @Description 开放使用的http del请求
     * @Author wifiunion
     * @Date 2016年5月6日 下午5:28:50
     */
    public static void HttpDelRequest_Asyn(Context context, String httpurl, String authtoken, String uuid,
                                           final BaseCallBack callback, final java.lang.reflect.Type type) {
        getInstance().HttpDelRequest_Asyn_Real(httpurl, authtoken, uuid, callback, type, context);
    }

    /**
     * @param authtoken
     * @param bitmap    图片对象
     * @return void
     * @Name HttpImgUpload_Asyn
     * @Description 开放使用的 图片上传方法
     * @Author wifiunion
     * @Date 2016年5月9日 上午9:36:39
     */
    public static void HttpImgUpload_Asyn(String authtoken, Bitmap bitmap, BaseCallBack callback) {
        getInstance().HttpImgUpload_Asyn_Real(authtoken, bitmap, callback);
    }


    /**
     * @param bitmap 图片对象
     * @return void
     * @Name HttpImgUpload_Asyn
     * @Description 开放使用的 图片上传方法
     * @Author wifiunion
     * @Date 2016年5月9日 上午9:36:39
     */
    public static void HttpImgUpload_Asyn_icloud(Bitmap bitmap, BaseCallBack callback) {
        getInstance().HttpImgUpload_Asyn_Real_icloud(bitmap, callback);
    }


    /**
     * @param request
     * @param type
     * @return void
     * @Name deliveryHttpPostResult
     * @Description TODO
     * @Author wifiunion
     * @Date 2016年5月6日 下午12:07:59
     */
    private void deliveryHttpPostResult(Request request, final BaseCallBack callback, final java.lang.reflect.Type type,
                                        final boolean needParse) {
        mOkHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(final Call call, final IOException e) {
//                callback.onNetFailed();
                sendFailedCallback(callback, null);
            }

            @Override
            public void onResponse(Call call, final Response response) {
                JSONObject jsonObject = null;
                try {
                    String respStr = response.body().string();
                    jsonObject = new JSONObject(respStr);
                    if (jsonObject.has("messageCode") && "SYS9999".equals(jsonObject.getString("messageCode"))) {

//                        callback.onServerFailed(jsonObject.getString("message"));
                        sendFailedCallback(callback, jsonObject.getString("message"));
                    } else {
                        if (jsonObject.has("result")) {
                            if (1 == jsonObject.getInt("result")) {
                                if (jsonObject.has("data")) {
                                    String result = jsonObject.getString("data");
//                                    callback.onSuccess(result);
                                    sendSuccessCallback(callback, result);
                                } else {
//                                    callback.onSuccess(null);
                                    sendSuccessCallback(callback, null);
                                }
                            } else {
                                String result = jsonObject.getString("message");
                                String msgCode = jsonObject.getString("messageCode");

                                if ((!TextUtils.isEmpty(msgCode)) && ("BUI0009".equals(msgCode) || "BUI0001".equals(msgCode))) {
                                    Intent intent = new Intent(Constants.LOGOUT_ACTION);
                                    if (!TextUtils.isEmpty(jsonObject.getString("message"))) {
                                        intent.putExtra("errormsg", jsonObject.getString("message"));
                                    } else {
                                        intent.putExtra("errormsg", "未知异常，请重新登录");
                                    }
                                    BaseApplication.mApplication.sendBroadcast(intent);
                                } else {
//                                    callback.onServerFailed(result);
                                    sendFailedCallback(callback, result);
                                }
                            }
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
//                    callback.onServerFailed(e.getMessage());
                    sendFailedCallback(callback, e.getMessage());
                }

            }
        });
    }

    /**
     * @param request
     * @param type
     * @return void
     * @Name deliveryHttpPutResult
     * @Description http put 请求的回调处理
     * @Author wifiunion
     * @Date 2016年5月6日 下午4:37:12
     */
    private void deliveryHttpPutResult(Request request, final BaseCallBack callback, final java.lang.reflect.Type type,
                                       final Context context) {
        mOkHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(final Call request, final IOException e) {
//                callback.onServerFailed(e.getMessage());
                sendFailedCallback(callback, null);
            }

            @Override
            public void onResponse(Call call, final Response response) {

                JSONObject jsonObject = null;

                try {
                    jsonObject = new JSONObject(response.body().string());
                    if (jsonObject.has("messageCode") && "SYS9999".equals(jsonObject.getString("messageCode"))) {
//                        callback.onServerFailed(jsonObject.getString("message"));
                        sendFailedCallback(callback, jsonObject.getString("message"));
                    } else {
                        if (jsonObject.has("result")) {
                            if (1 == jsonObject.getInt("result")) {
                                if (jsonObject.has("data")) {
                                    String obj = jsonObject.getString("data");
//                                    callback.onSuccess(obj);
                                    sendSuccessCallback(callback, obj);
                                }
                            } else {
//                                callback.onServerFailed(jsonObject.getString("message"));
                                sendFailedCallback(callback, jsonObject.getString("message"));
                            }
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
//                    callback.onServerFailed(e.getMessage());
                    sendFailedCallback(callback, e.getMessage());
                }

            }
        });
    }

    private void deliveryHttpDelResult(Request request, final BaseCallBack callback, final java.lang.reflect.Type type,
                                       final Context context) {

        mOkHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(final Call call, final IOException e) {
//                callback.onServerFailed(e.getMessage());
                sendFailedCallback(callback, null);
            }

            @Override
            public void onResponse(Call call, final Response response) {

                if (response.isSuccessful()) {
                    try {
                        JSONObject jsonObject = new JSONObject(response.body().string());
                        if (jsonObject.has("messageCode") && "SYS9999".equals(jsonObject.getString("messageCode"))) {
//                            callback.onServerFailed(jsonObject.getString("message"));
                            sendFailedCallback(callback, null);
                        } else {
                            if (jsonObject.has("result")) {
                                if (1 == jsonObject.getInt("result")) {
                                    if (jsonObject.has("data")) {
                                        String obj = jsonObject.getString("data");
//                                        callback.onSuccess(obj);
                                        sendSuccessCallback(callback, obj);
                                    }
                                } else {
                                    sendFailedCallback(callback, jsonObject.getString("message"));
//                                    callback.onServerFailed(jsonObject.getString("message"));
                                }
                            }
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                        sendFailedCallback(callback, e.getMessage());
//                        callback.onServerFailed(e.getMessage());
                    }
                } else {
                    sendFailedCallback(callback, null);
//                    callback.onNetFailed();
                }
            }

        });
    }

    /**
     * @param request
     * @return void
     * @Name deliveryImgUploadRequest
     * @Description TODO
     * @Author wifiunion
     * @Date 2016年5月9日 上午9:50:59
     */
    private void deliveryImgUploadRequest(Request request, final BaseCallBack callback) {

        mOkHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(final Call call, final IOException e) {
//                callback.onNetFailed();
                sendFailedCallback(callback, null);
            }

            @Override
            public void onResponse(Call call, final Response response) {

                if (response.isSuccessful()) {
                    try {
                        JSONObject jsonObject = new JSONObject(response.body().string());
                        if (jsonObject.has("messageCode") && "SYS9999".equals(jsonObject.getString("messageCode"))) {
//                            callback.onServerFailed(jsonObject.getString("message"));
                            sendFailedCallback(callback, jsonObject.getString("message"));
                        } else {
                            if (jsonObject.has("result")) {
                                if (1 == jsonObject.getInt("result")) {
                                    if (jsonObject.has("data")) {

                                        String obj = jsonObject.getString("data");
//                                        callback.onSuccess(obj);

                                        sendSuccessCallback(callback, obj);
                                    }
                                } else {
//                                    callback.onServerFailed(jsonObject.getString("message"));
                                    sendFailedCallback(callback, jsonObject.getString("message"));
                                }
                            }
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
//                        callback.onServerFailed(e.getMessage());
                        sendFailedCallback(callback, e.getMessage());
                    }
                } else {
//                    callback.onNetFailed();
                    sendFailedCallback(callback, null);
                }
            }

        });

    }

    /**
     * @param authtoken
     * @param bitmap
     * @return void
     * @Name HttpImgUpload_Asyn_Real
     * @Description TODO
     * @Author wifiunion
     * @Date 2016年5月9日 上午9:36:13
     */
    private void HttpImgUpload_Asyn_Real(String authtoken, Bitmap bitmap, final BaseCallBack callback) {
        byte[] data = null;
        if (null != bitmap) {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();

            bitmap.compress(Bitmap.CompressFormat.JPEG, 75, bos);
            data = bos.toByteArray();
            RequestBody fileBody = RequestBody.create(MEDIA_TYPE_IMG, data);

            MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM);


            builder.addPart(Headers.of("Content-Disposition", "form-data; name=file; filename=image.jpg"),
                    fileBody);

            RequestBody requestBody = builder.build();
            Request request = new Request.Builder().post(requestBody).addHeader("Authorization", authtoken)
                    .url(Constants.HTTP_URL_HEADER + Constants.HTTP_URL_UPLOAD).build();

            deliveryImgUploadRequest(request, callback);
        }

    }


    /**
     * @param bitmap
     * @return void
     * @Name HttpImgUpload_Asyn_Real
     * @Description TODO
     * @Author wifiunion
     * @Date 2016年5月9日 上午9:36:13
     */
    private void HttpImgUpload_Asyn_Real_icloud(Bitmap bitmap, final BaseCallBack callback) {
        byte[] data = null;
        if (null != bitmap) {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();

            bitmap.compress(Bitmap.CompressFormat.JPEG, 75, bos);
            data = bos.toByteArray();
            RequestBody fileBody = RequestBody.create(MEDIA_TYPE_IMG, data);

            MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM);


            builder.addPart(Headers.of("Content-Disposition", "form-data; name=file; filename=image.jpg"),
                    fileBody);

            RequestBody requestBody = builder.build();
            Request request = new Request.Builder().post(requestBody)
                    .url(Constants.HTTP_URL_ICLOUD + Constants.HTTP_URL_UPLOAD).build();

            deliveryImgUploadRequest(request, callback);
        }

    }


    public static void HttpDownload_Asyn(String packageurl, String dirpath, BaseCallBack callback) {
        getInstance()._downloadAsyn(packageurl, dirpath, callback);
    }


    public static void HttpUploadPackage_Asyn(String uploadPath, File file, BaseCallBack callback) {
        getInstance().UploadPackage_Asyn(uploadPath, file, callback);
    }

    public void UploadPackage_Asyn(String uploadPath, File file, final BaseCallBack callback) {

        MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM);
        String fileName = file.getName();
        RequestBody fileBody = RequestBody.create(MediaType.parse("application/x-www-form-urlencoded"), file);
        builder.addPart(Headers.of("Content-Disposition",
                "form-data; name=file;filename=" + fileName), fileBody);

        RequestBody requestBody = builder.build();
        Request request = new Request.Builder().post(requestBody).url(uploadPath).build();
        deliveryPackageUploadRequest(request, callback);
    }

    /**
     * 设置超时时间
     * 响应结束后再设置回头
     *
     * @param request
     * @param callback
     */
    private void deliveryPackageUploadRequest(Request request, final BaseCallBack callback) {


        mOkHttpClient = new OkHttpClient.Builder()
                .connectTimeout(120, TimeUnit.SECONDS)
                .readTimeout(250, TimeUnit.SECONDS)
                .writeTimeout(250, TimeUnit.SECONDS)
                .build();
        mOkHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(final Call call, final IOException e) {
                callback.onNetFailed();
                mOkHttpClient = new OkHttpClient.Builder()
                        .connectTimeout(30, TimeUnit.SECONDS)
                        .readTimeout(30, TimeUnit.SECONDS)
                        .writeTimeout(30, TimeUnit.SECONDS)
                        .build();
            }

            @Override
            public void onResponse(Call call, final Response response) {

                if (response.isSuccessful()) {
                    try {
                        JSONObject jsonObject = new JSONObject(response.body().string());
                        if (jsonObject.has("messageCode") && "SYS9999".equals(jsonObject.getString("messageCode"))) {
//                            callback.onServerFailed(jsonObject.getString("message"));
                            sendFailedCallback(callback, jsonObject.getString("message"));
                        } else {
                            if (jsonObject.has("result")) {
                                if (1 == jsonObject.getInt("result")) {
                                    if (jsonObject.has("data")) {

                                        String obj = jsonObject.getString("data");
//                                        callback.onSuccess(obj);

                                        sendSuccessCallback(callback, obj);
                                    }
                                } else {
//                                    callback.onServerFailed(jsonObject.getString("message"));
                                    sendFailedCallback(callback, jsonObject.getString("message"));
                                }
                            }
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
//                        callback.onServerFailed(e.getMessage());
                        sendFailedCallback(callback, e.getMessage());
                    }
                } else {
//                    callback.onNetFailed();
                    sendFailedCallback(callback, null);
                }
                mOkHttpClient = new OkHttpClient.Builder()
                        .connectTimeout(30, TimeUnit.SECONDS)
                        .readTimeout(30, TimeUnit.SECONDS)
                        .writeTimeout(30, TimeUnit.SECONDS)
                        .build();
            }


        });

    }


    /**
     * 异步下载文件
     *
     * @param url
     * @param destFileDir 本地文件存储的文件夹
     * @param callback
     */
    private void _downloadAsyn(final String url, final String destFileDir, final BaseCallBack callback) {
        final Request request = new Request.Builder().url(url).build();
        final Call call = mOkHttpClient.newCall(request);

        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
//                sendFailedStringCallback(request, e, callback);

//                sendFailedCallback(callback, null);
                ((BaseDownloadCallback) callback).onNetFailed();
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {

                InputStream is = null;
                byte[] buf = new byte[2048];
                int len = 0;
                FileOutputStream fos = null;
                try {

                    ResponseBody rb = response.body();
                    is = rb.byteStream();
                    if (callback instanceof BaseDownloadCallback) {
                        ((BaseDownloadCallback) callback).getPackageSize(rb.contentLength());

                    }

                    File dirPath = new File(destFileDir);
                    if (!dirPath.exists()) {
                        dirPath.mkdirs();
                    }

                    File file = new File(destFileDir, getFileName(url));
                    if (!file.exists()) {
                        file.createNewFile();
                    }
//                    Log.e(Constants.TAG, "filepath  " + file.getAbsolutePath());

                    int downLoadFileSize = 0;
                    fos = new FileOutputStream(file);
                    while ((len = is.read(buf)) != -1) {
                        fos.write(buf, 0, len);
                        if (callback instanceof BaseDownloadCallback) {
                            downLoadFileSize += len;
                            ((BaseDownloadCallback) callback).downloadPercent(downLoadFileSize);
                        }
                    }
                    fos.flush();
                    // 如果下载文件成功，第一个参数为文件的绝对路径
                    ((BaseDownloadCallback) callback).onSuccess(file.getAbsolutePath());
//                    sendSuccessCallback(callback,file.getAbsolutePath());

//                    ((BaseDownloadCallback) callback).onSuccess(downLoadFileSize);////????为什么要返回这个？？
                } catch (IOException e) {
                    e.printStackTrace();
                    ((BaseDownloadCallback) callback).onServerFailed(e.getMessage());
//                    sendFailedCallback(callback, e.getMessage());
                } finally {
                    try {
                        if (is != null)
                            is.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    try {
                        if (fos != null)
                            fos.close();
                    } catch (IOException e) {
                        e.printStackTrace();

                    }
                }

            }
        });

    }

    /**
     * cancel页面
     */
    public void cancelAll() {
        try {
            if (mOkHttpClient != null) {
                mOkHttpClient.dispatcher().cancelAll();
            }
        } catch (Exception E) {

        }
    }

    public interface StringCallback {
        void onFailure(Request request, IOException e);

        void onResponse(String response);
    }

    public static class Param {
        public Param() {
        }

        public Param(String key, String value) {
            this.key = key;
            this.value = value;
        }

        String key;
        String value;
    }

    /**
     * 成功返回 并在主线程更新UI
     *
     * @param callback
     * @param object
     */
    void sendSuccessCallback(final BaseCallBack callback, final Object object) {
        mDelivery.post(new Runnable() {
            @Override
            public void run() {
                callback.onSuccess(object);
            }
        });
    }

    ;

    /**
     * 失败返回，并在主线程返回数据
     */
    void sendFailedCallback(final BaseCallBack callback, final Object object) {

        mDelivery.post(new Runnable() {
            @Override
            public void run() {

                if (object == null) {
                    callback.onNetFailed();
                } else {
                    callback.onServerFailed(object);
                }
            }
        });
    }

    ;


}